package com.csjbot.snowbot_rogue.utils;

import android.support.annotation.NonNull;

import com.csjbot.csjbase.log.Csjlogger;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Random;

/**
 * Created by Administrator on 2016/8/12 0012.
 */
public class voiceParser {

    public static void parserVoice(String json, @NonNull VoiceParserCallBack callBack) {
        StringBuffer ret = new StringBuffer();

        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);

            if (joResult.getString("rc").endsWith("0")) {
                switch (joResult.getString("service")) {
                    case "music":
                        parseMusic(joResult, callBack);
                        break;
                    case "weather":
                        parseWeather(joResult, callBack);
                        break;
                    case "map":
                        parseMap(joResult, callBack);
                        break;
                    case "schedule":
                        parseSchedule(joResult, callBack);
                        break;
                    case "flower":
                        parseFlower(joResult, callBack);
                        break;
                    case "gift":
                        parseGift(joResult, callBack);
                        break;
                    case "cookbook":
                        parseCookbook(joResult, callBack);
                        break;
                    case "websearch":
                        parseWebSearch(joResult, callBack);
                        break;
                    case "translation":
                        parseTranslation(joResult, callBack);
                        break;
                    case "flight":
                        parserFlight(joResult, callBack);
                        break;
                    case "pm25":
                        parserPM25(joResult, callBack);
                        break;
                    case "train":
                        parseTrain(joResult, callBack);
                        break;
                    case "tv":
                        parseTV(joResult, callBack);
                        break;
                    case "telephone":
                        parseTelephone(joResult, callBack);
                        break;
                    case "app":
                        parseApp(joResult, callBack);
                        break;
                    case "restaurant":
                        parseRestaurant(joResult, callBack);
                        break;
                    case "hotel":
                        parseHotel(joResult, callBack);
                        break;
                    case "stock":
                        parseStock(joResult, callBack);
                        break;
                    case "openQA":
                        parseOpenQA(joResult, callBack);
                        break;
                    default:
                        callBack.parserBaike(joResult.getJSONObject("answer").getString("text"));
                        break;
                }
            } else {
                int errorCode = Integer.parseInt(joResult.getString("rc"));
                callBack.parserError(errorCode);
            }
        } catch (JSONException e) {
            Csjlogger.error(e.getMessage());
            callBack.parserError(6);
        }
    }

    /**
     * 查询XX股票
     * XX股票是涨了还是跌了
     */
    private static void parseStock(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String name = slot.isNull("name") ? slot.getString("code") : slot.getString("name");
        String str = "小雪这就为您呈现" + name + "股票的信息";
        if (callBack != null) {
            callBack.parseStock(str, joResult.getJSONObject("webPage").getString("url"));
        }
    }

    private static void parseOpenQA(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        String answer_text = joResult.getJSONObject("answer").getString("text");
        switch (answer_text) {
            case "csjat_move_dance":
                callBack.parseMoveAction(5);
                break;
            case "csjat_move_forward":
                callBack.parseMoveAction(1);
                break;
            case "csjat_move_back":
                callBack.parseMoveAction(2);
                break;
            case "csjat_move_left":
                callBack.parseMoveAction(3);
                break;
            case "csjat_move_right":
                callBack.parseMoveAction(4);
                break;
            case "csjat_move_stop":
                callBack.parseMoveAction(0);
                break;
            default:
                callBack.parserBaike(answer_text);
                break;
        }
    }

    private static void parseCookbook(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String name = !slot.isNull("dishName") ? slot.getString("dishName") : (slot.isNull("ingredient") ? slot.getString("keyword") : slot.getString("ingredient"));
        JSONArray array = joResult.getJSONObject("data").getJSONArray("result");
        int len = array.length();

        if (callBack != null) {
            callBack.parseFlower("小雪这就为您搜索" + name + " ,共搜到" + len + "个结果，这就为您呈现",
                    joResult.getJSONObject("webPage").getString("url"));
        }
    }

    /**
     * 帮我在XX（酒店、宾馆）订个房间
     * 帮我找一下XX（地点）有哪些宾馆
     */
    private static void parseHotel(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String date = slot.getJSONObject("checkinDate").isNull("dateOrig") ? "今天" : slot.getJSONObject("checkinDate").getString("dateOrig");
        String name = slot.isNull("name") ? "酒店" : slot.getString("name");
        String str = "";
        JSONObject location = slot.getJSONObject("location");
        if (location.isNull("city")) {
            if (location.isNull("area")) {
                String address = location.isNull("province") ? location.getString("country") : location.getString("province");
                str = "请问你想查询" + address + "哪个城市的宾馆";
            } else {
                str = "小雪这就为您搜索" + date + location.getString("area") + name;
            }
        } else {
            String city = location.getString("city").equals("CURRENT_CITY") ? "附近的" : location.getString("city");
            if (location.isNull("area")) {
                str = "小雪这就为您搜索" + date + city + name;
            } else {
                str = "小雪这就为您搜索" + date + city + date + location.getString("area") + name;
            }
        }
        callBack.paserAndSay(str);
    }

    /**
     * XX（地点）有什么好吃的
     * 我想吃XX
     */
    private static void parseRestaurant(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        JSONObject location = slot.getJSONObject("location");
        String kind = !slot.isNull("name") ? slot.getString("name") : slot.getString("category");
        String city = location.getString("city");
        String str = "";
        if (city.equals("CURRENT_CITY") && location.isNull("area")) {
            str = "小雪这就为您搜索" + kind;
        } else if (location.isNull("area")) {
            str = "小雪这就为您搜索" + city + "的" + kind;
        } else {
            str = "小雪这就为您搜索" + city + location.getString("area") + "的" + kind;
        }
        callBack.paserAndSay(str);
    }


    private static void parseApp(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String str = "";
        if (!slot.isNull("name") && slot.getString("name").equals("相机") && joResult.getString("operation").equals("LAUNCH")) {
            str = "小雪这就为您打开相机";
            callBack.paresApp(str);
        }
    }

    /**
     * 打电话给XX（人或电话号码）
     */
    private static void parseTelephone(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        Csjlogger.debug("service");
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String str = "";
        if (joResult.getJSONObject("semantic").isNull("slots") || (slot.isNull("name") && slot.isNull("code"))) {
            str = "请问您想打给谁";
        } else {
            String name = !slot.isNull("name") ? slot.getString("name") : slot.getString("code");
            str = "小雪这就为您拨打" + name + "的电话";
        }
        callBack.paserAndSay(str);
    }

    /**
     * XX(节目名)哪个台放
     * 湖南卫视节目表
     * 有什么好看的电视吗/电影吗
     */
    private static void parseTV(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        // TODO check
        String str = "";
        if (joResult.getJSONObject("data").isNull("result")) {
            str = "小雪这就为您呈现搜索结果";
        } else {
            JSONArray array = joResult.getJSONObject("data").getJSONArray("result");
            int len = array.length();
            str = "小雪已搜索到" + len + "个结果，这就为您呈现";
        }
        if (callBack != null) {
            callBack.parserWebService(str, joResult.getJSONObject("webPage").getString("url"));
        }
    }

    /**
     * 明天徐州到南京的高铁
     */
    private static void parseTrain(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        // TODO 处理失败
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");

        String Url = "小雪为您找到%s从%s到%s的%s";
        String date = !slot.isNull("startDate") ? slot.getJSONObject("startDate").getString("dateOrig") : "今天";
        String startLoc = slot.getJSONObject("startLoc").getString("city");
        String endLoc = slot.getJSONObject("endLoc").getString("city");
        String category = !slot.isNull("category") ? slot.getString("category") : "火车";

        callBack.paserAndSay(String.format(Url, date, startLoc, endLoc, category));
    }

    /**
     * XX（地方名）空气质量怎么样
     * XX（地方）空气好不好
     */
    private static void parserPM25(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject location = joResult.getJSONObject("semantic").getJSONObject("slots").getJSONObject("location");
        JSONArray results = joResult.getJSONObject("data").getJSONArray("result");
        String url = joResult.getJSONObject("webPage").getString("url");
        String str = "";

        if (location.isNull("city")) {
            if (location.isNull("area")) {
                String address = location.isNull("province") ? location.getString("country") : location.getString("province");
                str = "请问您想查询的是" + address + "哪个城市的空气质量";
                callBack.paserAndSay(str);
            } else {
                String area = location.getString("area");
                for (int i = 0; i < results.length(); i++) {
                    JSONObject resault = (JSONObject) results.get(i);
                    Csjlogger.debug(resault.getString("subArea"));

                    if (resault.getString("subArea").equals(area)) {
                        str = area + "pm25，" +
                                resault.getString("pm25") + "， 空气质量指数，" +
                                resault.getString("aqi") + "，空气质量 " +
                                resault.getString("quality");
                    }
                }
                callBack.parserWeather(str, url);
            }
        } else {
            if (location.getString("city").equals("CURRENT_CITY")) {
                str = "请问您想查询的是哪个城市的空气质量";
                callBack.paserAndSay(str);
            } else {
                String area = location.isNull("area") ? location.getString("cityAddr") : location.getString("area");
                for (int i = 0; i < results.length(); i++) {
                    JSONObject resault = (JSONObject) results.get(i);
                    if (resault.getString("subArea").equals(area)) {
                        str = area + "pm25，" +
                                resault.getString("pm25") + "， 空气质量指数，" +
                                resault.getString("aqi") + "，空气质量 " +
                                resault.getString("quality");
                        Csjlogger.debug(resault.getString("subArea"));
                        break;
                    }
                }
                callBack.parserWeather(str, url);
            }
        }
    }

    private static void parserFlight(JSONObject joResult, VoiceParserCallBack callBack) {
        callBack.paserAndSay("机票查询功能暂时未开放，小雪接下来会为您开放的");
    }

    /**
     * 帮我订个礼品
     * （对话必须包含"订"或者"订购"、"礼品"）
     */
    private static void parseGift(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String name = !slot.isNull("name") ? slot.getString("name") : slot.getString("category");
        JSONArray array = joResult.getJSONObject("data").getJSONArray("result");
        int len = array.length();

        if (callBack != null) {
            callBack.parseFlower("小雪这就为您搜索" + name + " ,共搜到" + len + "个结果，这就为您呈现",
                    joResult.getJSONObject("webPage").getString("url"));
        }
    }

    /**
     * 帮我订一束花
     * 帮我订一束玫瑰（或百合、其他花名）
     * （对话必须包含"订"或者"订购"/束）
     */
    private static void parseFlower(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        String name = joResult.getJSONObject("semantic").getJSONObject("slots").getString("category");
        JSONArray array = joResult.getJSONObject("data").getJSONArray("result");
        int len = array.length();

        if (callBack != null) {
            callBack.parseFlower("小雪这就为您搜索" + name + " ,共搜到" + len + "个结果，这就为您呈现",
                    joResult.getJSONObject("webPage").getString("url"));
        }
    }

    private static void parseTranslation(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");

        String target = slot.getString("target");
        String source = "zh";
        String content = slot.getString("content");
        String targetSay = "英语";
        String url = "http://fanyi.baidu.com/?aldtype=16047#%s/%s/%s";

        switch (target) {
            case "ja":
                target = "jp";
                targetSay = "日语";
                break;
            case "ko":
                target = "kor";
                targetSay = "韩语";
                break;
            default:
                break;
        }

        StringBuilder sb = new StringBuilder();
        sb.append("小雪这就为您把").append(content).append("翻译成").append(targetSay);

        try {
            callBack.parserWebService(sb.toString(), String.format(url, source, target, URLDecoder.decode(content, "utf-8")));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param
     * @Description: 网络查询
     * @author Administrator
     * @time 2016/8/11 0011
     * <p/>
     * 帮我XX（淘宝、百度等搜索引擎）XX（要搜索的）
     */
    private static void parseWebSearch(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        // TODO 有BUG {"semantic":{"slots":{"keywords":"乔布斯"}},"rc":0,"operation":"QUERY","service":"video","text":"百度乔布斯"}
        String sayString = "";
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String channel = !slot.isNull("channel") ? slot.getString("channel") : "baidu";
        String keywords = slot.getString("keywords");
        String sayChannel = "百度";
        String channelUrl = "https://www.baidu.com.cn/s?wd=%s&cl=3";
        switch (channel) {
            case "google":
//                channelUrl = "www.google.com";
//                sayChannel = "谷歌";
                sayString = "小雪提醒您，国内可上不了谷歌哦";
                break;
            case "taobao":
                channelUrl = "https://s.taobao.com/search?q=%s";
                sayChannel = "淘宝";
                sayString = "小雪这就为您用" + sayChannel + " ,搜索" + keywords;
                break;
            default:
                break;
        }
        callBack.parserWebService(sayString, String.format(channelUrl, keywords));
    }

    /**
     * @param
     * @Description:
     * @author Administrator
     * @time 2016/8/11 0011
     * <p/>
     * 明天早上八点钟叫我
     * 提醒我下午四点有个会议
     */
    private static void parseSchedule(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject slots = joResult.getJSONObject("semantic").getJSONObject("slots");
        JSONObject datetime = slots.getJSONObject("datetime");
        String dateOrig = datetime.isNull("dateOrig") ? "今天" : datetime.getString("dateOrig");
        String str = "小雪这就为您设置" + dateOrig + "的闹钟";
        if (!datetime.isNull("timeOrig")) {
            String timeOrig = datetime.getString("timeOrig");
            str = "小雪这就为您设置" + dateOrig + timeOrig + "的闹钟";
        }
        callBack.parserSchedule(str);
    }


    /**
     * @param
     * @Description: 解析地图场景
     * @author Administrator
     * @time 2016/8/11 0011
     * TODO 需要做的更加好
     */
    private static void parseMap(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        StringBuilder sb = new StringBuilder();

        switch (joResult.getString("operation")) {
            case "ROUTE":
                JSONObject endLocObj = joResult.getJSONObject("semantic").getJSONObject("slots").getJSONObject("endLoc");
                String end = endLocObj.isNull("city") ? endLocObj.getString("area") : endLocObj.getString("city");
                JSONObject startLocObj = joResult.getJSONObject("semantic").getJSONObject("slots").getJSONObject("startLoc");
                String start = startLocObj.isNull("city") ? startLocObj.getString("area") : startLocObj.getString("city");

                if (start.equalsIgnoreCase("CURRENT_CITY")) {
                    start = "昆山";
                }

                sb.append("小雪是路盲，不知道从").append(start).append("到").append(end).append("怎么去").toString();
                break;
            case "POSITION":
                JSONObject location = joResult.getJSONObject("semantic").getJSONObject("slots").getJSONObject("location");
                String area = location.isNull("area") ? location.getString("city") : location.getString("area");
                sb.append("小雪这就为您定位").append(area);
                break;
            default:
                break;
        }

        callBack.parseMap(sb.toString());
    }

    /**
     * 今天天气怎么样
     * 明天昆山会下雨吗
     */
    private static void parseWeather(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONObject dataTimeObj = joResult.getJSONObject("semantic").getJSONObject("slots").getJSONObject("datetime");
        JSONArray results = joResult.getJSONObject("data").getJSONArray("result");
        boolean checkDateOut = false;

        // 小雪要说出的天气
        String dateString = "今天";

        // 确实获取的准确日子
        String date = dataTimeObj.getString("date");
        String str = "";

        if (!date.equals("CURRENT_DAY")) {
            dateString = dataTimeObj.getString("dateOrig");
        } else {
            JSONObject resault = (JSONObject) results.get(0);

            str = resault.getString("city") + dateString + "天气，" +
                    resault.getString("wind") + "，" +
                    resault.getString("weather") + "，" +
                    resault.getString("tempRange");

            if (!resault.isNull("airQuality") && !resault.getString("airQuality").isEmpty()) {
                str += ",  空气质量" + resault.getString("airQuality");
            }
        }
        for (int i = 0; i < results.length(); i++) {
            JSONObject resault = (JSONObject) results.get(i);
            Csjlogger.debug(resault.getString("date"));

            if (resault.getString("date").equals(date)) {
                str = resault.getString("city") + dateString + "天气，" +
                        resault.getString("wind") + "，" +
                        resault.getString("weather") + "，" +
                        resault.getString("tempRange");

                if (!resault.isNull("airQuality") && !resault.getString("airQuality").isEmpty()) {
                    str += ",  空气质量" + resault.getString("airQuality");
                }

                checkDateOut = false;
                break;
            }
            checkDateOut = true;
        }
        if (checkDateOut) {
            str = "您说的日子离今天太远啦，小雪没有办法为您查到。";
        }
        if (callBack != null) {
            JSONObject objURL = joResult.getJSONObject("webPage");
            callBack.parserWeather(str, objURL.getString("url"));
        }
    }

    private static void parseMusic(JSONObject joResult, VoiceParserCallBack callBack) throws JSONException {
        JSONArray ja = joResult.getJSONObject("data").getJSONArray("result");
        // TODO 这个要测试
        if (callBack != null) {
            if (ja.length() > 0) {
                JSONObject selectSong = ja.getJSONObject(new Random().nextInt(ja.length()));
                callBack.parserMusic(true, selectSong.getString("downloadUrl"), selectSong.getString("singer"), selectSong.getString("name"));
            } else {
                JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
                callBack.parserMusic(false, "", slot.getString("artist"), slot.getString("song"));
            }
        }
    }
}
